package ejb.contentManagement;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.security.RolesAllowed;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import ejb.dto.PeriodDTO;
import entities.Period;


@Stateless
public class PeriodBean implements PeriodMgr {
	
	@PersistenceContext
    private EntityManager em;
	
	/**
	 * Retrieve entity Period from the associated Id
	 * @param id
	 * @return entity Period associated to the <code>id</code>
	 */
	public Period getPeriod(int id) {
		return em.find(Period.class, id);
	}
	
	/**
	 * Retrieve all Period entities
	 * @return all Period entities
	 */
	public List<Period> getAllPeriods() {
    	return em.createNamedQuery("Period.findAll", Period.class)
                .getResultList();
    }
	
	/**
	 * Retrieve entity Period from the associated Id and convert it to corresponding PeriodDTO
	 */
	@Override
	public PeriodDTO getPeriodDTO(int id) {
		return  convertToDTO(getPeriod(id));
    }
	
	/**
	 * Retrieve all Period entities and convert them into corresponding list of PeriodDTO
	 */
	@Override
	public List<PeriodDTO> getAllPeriodsDTO() {
		List<Period> list = getAllPeriods();
		List<PeriodDTO> newList = new ArrayList<PeriodDTO>();
		for(Period obj : list) {
			newList.add(convertToDTO(obj));
		}
		return newList;
	}
	
	/**
	 * Convert Period entity (parameter <code>p</code>) into corresponding PeriodDTO
	 * @param p
	 * @return converted PeriodDTO
	 */
	public static PeriodDTO convertToDTO(Period p) {
		if(p == null){
			return null;
		}
		PeriodDTO dto = new PeriodDTO();
		dto.setId(p.getId());
		dto.setName(p.getName());
		dto.setDescription(p.getDescription());
		dto.setFromDate(p.getFromDate());
		dto.setToDate(p.getToDate());
		return dto;
	}
	
	/**
	 * Retrieve entity Period from the associated Id and delete the corresponding element from the database
	 */
	@Override
	@RolesAllowed({"ADMINS"})
	public boolean deletePeriod(int id) {
		try{
			em.remove(em.find(Period.class, id));
			em.flush();
		}
		//Catch exceptions in the delete operation from database
		catch(Exception e){
			return false;
		}
		return true;
	}
	
	/**
	 * Create entity Period from corresponding PeriodDTO and update corresponding element in database
	 */
	@Override
	@RolesAllowed({"ADMINS"})
	public boolean updatePeriod(PeriodDTO updatedPeriod) {
		if(updatedPeriod.getName().equals("") || 
			updatedPeriod.getName().startsWith(" ") || 
			updatedPeriod.getName()==null || 
			updatedPeriod.getFromDate() == null || 
			updatedPeriod.getToDate() == null || 
			updatedPeriod.getToDate().before(updatedPeriod.getFromDate()))
			return false;
		try{
			em.merge(new Period(updatedPeriod));
			em.flush();
		}
		//Catch exception in the update operation of database
		catch(Exception e){
			return false;
		}
		return true;
	}
	
	/**
	 * Create entity Period from corresponding PeriodDTO and insert new corresponding element in database
	 */
	@Override
	@RolesAllowed({"ADMINS"})
	public boolean insertPeriod(PeriodDTO newPeriod) {
		List<PeriodDTO> list = getAllPeriodsDTO(); 
		for(PeriodDTO p : list)
			if (p.getFromDate() == newPeriod.getFromDate() && p.getToDate() == newPeriod.getToDate())
				return false;
		
		if(newPeriod.getName().equals("") ||
			newPeriod.getName().startsWith(" ") ||
			newPeriod.getName()==null || 
			newPeriod.getFromDate() == null || 
			newPeriod.getToDate() == null ||
			newPeriod.getToDate().before(newPeriod.getFromDate()))
			return false;
		try{
			em.persist(new Period(newPeriod));
			em.flush();
		}
		//Catch exceptions in the insert operation in database
		catch(Exception e){
			return false;
		}
		return true;
	}
	
	
}
